#include "SingleLinkedList.h"

Node* init_list() {
    Node* list = (Node*)malloc(sizeof(Node));
    list->data = 0;
    list->next = NULL;
    return list;
}

Node* create_node(ElemType data, Node* next) {
    Node* new_node = (Node*)malloc(sizeof(Node));
    new_node->data = data;
    new_node->next = next;
    return new_node;
}

void add_tail(Node* list, ElemType data) {
    Node* new_node = create_node(data, NULL);
    while (list->next != NULL) {
        list = list->next;
    }
    list->next = new_node;
}

void add_head(Node* list, ElemType data) {
    Node* new_node = create_node(data, list->next);
    list->next = new_node;
}

void add_pos(Node* list, ElemType data, int pos) {
    if (pos < 1) {
        return;
    }
    Node* new_node = create_node(data, NULL);
    // 当pos大于链表长度时，直接在链表尾部添加新节点
    while (--pos && list->next != NULL) {
        list = list->next;
    }
    new_node->next = list->next;
    list->next = new_node;
}

void del_head(Node* list) {
    if (list->next == NULL) {
        return;
    }
    Node* del = list->next;
    list->next = del->next;
    free(del);
}

void del_tail(Node* list) {
    if (list->next == NULL) {
        return;
    }
    while (list->next->next != NULL) {
        list = list->next;
    }
    free(list->next);
    list->next = NULL;
}

void del_pos(Node* list, int pos) {
    if (pos < 1) {
        return;
    }
    // 当pos大于链表长度时，直接删除链表尾部节点
    while (--pos && list->next != NULL) {
        list = list->next;
    }
    Node* del = list->next;
    if (del == NULL) {
        return;
    }
    list->next = del->next;
    free(del);
}

ElemType get_val(Node* list, int pos) {
    if (pos < 1) {
        printf("get_val: illegal range\n");
        return -1;
    }
    while (pos-- && list->next != NULL) {
        list = list->next;
        if (list == NULL) {
            printf("get_val: Out of range\n");
            return -1;
        }
    }
    if (pos != -1) {
        printf("get_val: Out of range\n");
        return -1;
    }
    return list->data;
}

ElemType get_head(Node* list) {
    return list->next == NULL ? -1 : list->next->data;
}

ElemType get_tail(Node* list) {
    while (list->next != NULL) {
        list = list->next;
    }
    return list->data;
}

int get_len(Node* list) {
    int len = 0;
    for (Node* cur = list->next; cur != NULL; cur = cur->next) {
        len++;
    }
    return len;
}

int is_empty(Node* list) { return list == NULL || list->next == NULL; }

void print_list(Node* list) {
    printf("[HEAD >> ");
    while (list->next != NULL) {
        list = list->next;
        printf("%d >> ", list->data);
    }
    printf("NULL]\n");
}

void clear_list(Node* list) {
    while (list->next != NULL) {
        Node* del = list->next;
        list->next = del->next;
        free(del);
    }
    free(list);
}